<template>
    <a-card title="楼房分户" class="building-card">
        <a-steps :current="currentStep" :items="steps" class="steps-container" />

        <div class="content-container">
            <div class="draw-section">
                <a-button type="primary" size="large" @click="activeDraw" class="draw-button">
                    <template #icon>
                        <EditOutlined />
                    </template>
                    点击绘制
                </a-button>
            </div>

            <div class="table-section">
                <a-table size="middle" bordered :data-source="buildingData" :columns="buildingColumns"
                    :pagination="false" class="building-table">
                    <template #bodyCell="{ column, text, record }">
                        <template v-if="['posPrefix', 'unit'].includes(column.dataIndex)">
                            <div>
                                <a-input v-model:value="record[column.dataIndex]" class="editable-input" />
                            </div>
                        </template>
                    </template>
                </a-table>
            </div>

            <div class="floor-section" v-if="currentStep === 2 && showDivide">
                <div class="height-inputs">
                    <div class="input-group">
                        <span class="label">楼层数:</span>
                        <a-input-number v-model:value="floorNum" :min="0" :max="100" />
                    </div>
                </div>
            </div>

            <div class="action-section">
                <a-space>
                    <a-button v-if="currentStep < steps.length - 1" type="primary" @click="nextStep">
                        下一步
                    </a-button>
                    <a-button v-if="showDivide" @click="divideFloor">
                        楼房分层
                    </a-button>
                    <a-button v-if="currentStep == steps.length - 1 && updateActive" type="primary" @click="updateInfo">
                        生成数据
                    </a-button>
                </a-space>
            </div>
        </div>
    </a-card>
</template>

<script setup>
import { ref } from 'vue';
import { message } from 'ant-design-vue';
import { addBuilding, addUnit, addHousehold } from '../api/api';
import * as Cesium from 'cesium';
import { EditOutlined } from '@ant-design/icons-vue';
import { changeCartesin3ToGeoJson, polygonCut, cartesian3ToDegreesHeight } from '@/cesiumTools/utils';
import DrawTool from '../cesiumTools/drawTool';
import { useMapData } from '@/store';

const mapStore = useMapData();
let viewer = mapStore.Viewer;
const drawTool = new DrawTool(viewer);
const currentStep = ref(0);
const showDivide = ref(false);
const updateActive = ref(false);
const minHeight = ref(0);
const divideHeight = ref(0);
const maxHeight = ref(0);
const floorNum = ref(0);
const itemHeight = ref(0);

const buildingData = ref([]);
const buildingColumns = ref([{
    title: '楼栋名称',
    dataIndex: 'posPrefix',
    align: 'center',
    width: '60%',
    ellipsis: true
}, {
    title: '单元',
    dataIndex: 'unit',
    align: 'center',
    width: '40%'
}])

const steps = ref([
    {
        title: '区域绘制',
        key: '区域绘制'
    }, {
        title: '户型切分',
        key: '户型切分'
    }, {
        title: '楼房分层',
        key: '楼房分层'
    }
])

const nextStep = () => {
    // 只有区域绘制数据有值的时候，才能往下走
    if (buildingData.value?.length) {
        currentStep.value++
    } else {
        message.warn('请先绘制区域')
    }
}

// 全局变量声明
let lastDrawEnt
let drawEntLisener
let polygonGeo

// 绘制矩形
const activeDraw = () => {
    if (currentStep.value === 0) {
        // 只删除楼房相关的实体，保留标记点和路线
        viewer.entities.values.forEach(entity => {
            if (entity.name && typeof entity.name === 'string' && entity.name.includes('楼栋')) {
                viewer.entities.remove(entity)
            }
        })
        drawTool.active(drawTool.DrawTypes.Polygon)
        drawEntLisener = (drawEnt, postions) => {
            const { geojson, positionLng } = changeCartesin3ToGeoJson(postions, 'polygon')
            if (geojson) {
                polygonGeo = geojson
                // 直接存储 GeoJSON 数据
                buildingData.value[0] = {
                    position: positionLng,  // 存储坐标数组而不是字符串
                    posPrefix: 'xxx小区xxx楼栋',
                    unit: '1'
                }
                lastDrawEnt = drawEnt
                drawTool.DrawEndEvent.removeEventListener(drawEntLisener)
            }
        }
        drawTool.DrawEndEvent.addEventListener(drawEntLisener)
    } else if (currentStep.value === 1) {
        // 进行户型裁剪
        drawTool.active(drawTool.DrawTypes.Polyline)
        drawEntLisener = (drawEnt, postions) => {
            if (postions?.length) {// 确保有绘制点
                // 将绘制的线条转换为GeoJSON格式
                const { geojson: lineJson } = changeCartesin3ToGeoJson(postions, 'polyline')
                // 用这条线切割原来的楼栋区域
                const polygonCollection = polygonCut(polygonGeo, lineJson)
                if (polygonCollection) {
                    // 将切割后的区域加载到地图上显示
                    Cesium.GeoJsonDataSource.load(polygonCollection, { clampToGround: true }).then(info => {
                        // 移除原来的楼栋实体，避免重复显示
                        if (lastDrawEnt) {
                            viewer.entities.remove(lastDrawEnt)
                        }
                        lastDrawEnt = null

                        // 遍历切割后的每个区域，设置样式
                        info.entities.values.forEach((item, index) => {
                            // 为每个区域设置随机颜色
                            item.polygon.material = Cesium.Color.fromRandom({ alpha: 0.5 })
                            viewer.entities.add(item)
                            item.name = index
                        })
                        // 直接存储polygonCollection的数据
                        buildingData.value = polygonCollection.features.map((feature, index) => ({
                            key: index,
                            position: feature.geometry.coordinates[0],
                            posPrefix: buildingData.value[0].posPrefix,
                            unit: index + 1
                        }))
                        drawTool.DrawEndEvent.removeEventListener(drawEntLisener)
                    })
                }
            }
        }
        drawTool.DrawEndEvent.addEventListener(drawEntLisener)
    } else {
        // 楼栋分层
        drawTool.active(drawTool.DrawTypes.Point)
        drawEntLisener = (drawEnt, positions) => {
            if (positions.length === 3) {
                // 直接使用 cartesian3ToDegreesHeight 获取高度
                const heights = positions.map(item => cartesian3ToDegreesHeight(item)[2])
                //设置三个高度值
                minHeight.value = heights[0]
                divideHeight.value = heights[1]
                maxHeight.value = heights[2]
                //显示分层效果
                showDivide.value = true
            } else {
                message.warn('请绘制底层，二楼以及楼栋的最高点')
                return
            }
            drawTool.DrawEndEvent.removeEventListener(drawEntLisener)
        }
        drawTool.DrawEndEvent.addEventListener(drawEntLisener)
    }
}

// 设置楼层
const primitivesEffect = []
const divideFloor = () => {
    if (floorNum.value) {
        itemHeight.value = (maxHeight.value - divideHeight.value) / (floorNum.value - 1)
        buildingData.value.forEach((item) => {
            // 直接使用存储的坐标数组
            const positionArr = item.position

            for (let i = 0; i < floorNum.value; i++) {
                let height, extrudedHeight
                if (i == 0) {
                    height = minHeight.value
                    extrudedHeight = divideHeight.value
                } else {
                    height = divideHeight.value + (i - 1) * itemHeight.value
                    extrudedHeight = divideHeight.value + i * itemHeight.value
                }

                // 为每个单元和楼层生成随机颜色
                const randomColor = Cesium.Color.fromRandom({
                    alpha: 0.5,  // 设置透明度
                    minimumRed: 0.1,
                    minimumGreen: 0.1,
                    minimumBlue: 0.1,
                    maximumRed: 0.9,
                    maximumGreen: 0.9,
                    maximumBlue: 0.9
                })

                // 创建分类图元，使用随机颜色
                let primitive = new Cesium.ClassificationPrimitive({
                    //定义几何实例
                    geometryInstances: new Cesium.GeometryInstance({
                        //定义几何
                        geometry: new Cesium.PolygonGeometry({
                            //设置多边形的顶点
                            polygonHierarchy: new Cesium.PolygonHierarchy(
                                Cesium.Cartesian3.fromDegreesArray(positionArr.flat())
                            ),
                            height,// 底部高度
                            extrudedHeight, // 顶部高度
                        }),
                        // 设置颜色属性
                        attributes: {
                            color: Cesium.ColorGeometryInstanceAttribute.fromColor(randomColor),
                        },
                    }),
                    //告诉 Cesium 这个图元要显示在 3D 模型上
                    classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
                });
                // 将分类图元添加到primitivesEffect数组中   
                primitivesEffect.push(primitive)
                // 将分类图元添加到场景中
                viewer.scene.primitives.add(primitive);
                // 设置生成数据按钮为激活状态
                updateActive.value = true
            }
        })
    }
}

// 上传服务
const updateInfo = async () => {
    // 添加楼栋
    const buildingInfo = {
        name: buildingData.value[0]?.posPrefix || '未命名楼栋',
        polygon: {
            type: 'Polygon',
            coordinates: [buildingData.value[0].position]  // 直接使用存储的坐标数组
        },
        floors_num: floorNum.value
    }
    const buildingRes = await addBuilding(buildingInfo)
    if (buildingRes?.code !== 200) {
        message.error("添加楼栋失败")
        return
    }

    const buildingId = buildingRes.data.id

    // 添加单元
    // 遍历 buildingData 中的每个单元
    for (const unit of buildingData.value) {
        const unitInfo = {
            building_id: buildingId,
            number: parseInt(unit.unit || '1'),
            polygon: {
                type: 'Polygon',
                //切割后每个区域的坐标,要把一维数组变成二维数组,因为GeoJSON的polygon类型要求
                coordinates: [unit.position]
            }
        }
        const unitRes = await addUnit(unitInfo)
        if (unitRes?.code !== 200) {
            message.error("添加单元失败")
            return
        }

        const unitId = unitRes.data.id
        // 添加住户
        for (let i = 0; i < floorNum.value; i++) {
            const householdInfo = {
                unit_id: unitId,
                building_name: buildingInfo.name,
                unit_number: unitInfo.number.toString(),
                floor_num: i + 1,
                min_height: i === 0 ? minHeight.value : divideHeight.value + (i - 1) * itemHeight.value,
                max_height: i === 0 ? divideHeight.value : divideHeight.value + i * itemHeight.value,
                house_address: `${i + 1}层${unitInfo.number}单元`,
                house_type: '普通住宅',
                built_area: 100,
                orientation: '南',
                property_type: 1
            }
            const householdRes = await addHousehold(householdInfo)
            if (householdRes?.code !== 200) {
                message.error("添加住户失败")
                return
            }
        }
    }

    message.success("数据生成成功")

    // 刷新页面
    setTimeout(() => {
        window.location.reload()
    }, 1000)
}
</script>

<style scoped>
.building-card {
    width: 600px;
    pointer-events: all;
}

.steps-container {
    margin-bottom: 16px;
}

.content-container {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.draw-section {
    display: flex;
    justify-content: center;
}

.draw-button {
    width: 200px;
    height: 40px;
}

.table-section {
    margin: 0;
}

.building-table {
    margin-bottom: 12px;
}

:deep(.ant-table-tbody > tr > td) {
    padding: 4px 8px;
    height: 32px;
}

:deep(.ant-table-thead > tr > th) {
    padding: 4px 8px;
    height: 32px;
}

.editable-input {
    margin: -5px 0;
}

.editable-row-operations {
    display: flex;
    justify-content: center;
    gap: 8px;
}

.floor-section {
    padding: 12px;
    background: #f5f5f5;
    border-radius: 4px;
}

.height-inputs {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.input-group {
    display: flex;
    align-items: center;
    gap: 8px;
}

.input-group .label {
    min-width: 60px;
}

.action-section {
    display: flex;
    justify-content: flex-end;
    margin-top: 12px;
}
</style>